home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / TGE129C.ZIP / SOURCE / 320X400.ASM < prev    next >
Assembly Source File  |  1993-08-20  |  31KB  |  1,589 lines

  1. ; 320x400x256 (requires register-compatible VGA+)
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5.  
  6. IDEAL
  7. P486N            ; 386 code, but we want 486 alignment
  8. MODEL LARGE
  9.  
  10.  
  11. SCREEN_WIDE    =    320
  12. SCREEN_DEEP    =    400
  13. NUM_COLOURS    =    256
  14.  
  15.  
  16.         CODESEG
  17.         ORG    0
  18.  
  19. ;*** Signature
  20.             db    'TGE3'
  21. ;*** Non-I/O functions
  22. _initGraphics        dw    initGraphics        ; initGraphics
  23.             dw    ?
  24. _deInitGraphics        dw    0            ; deInitGraphics
  25.             dw    ?
  26. _setPaletteReg        dw    setPaletteReg        ; setPaletteReg
  27.             dw    ?
  28. _getPaletteReg        dw    getPaletteReg        ; getPaletteReg
  29.             dw    ?
  30. _setBlockPalette    dw    setBlockPalette        ; setBlockPalette
  31.             dw    ?
  32. _getBlockPalette    dw    getBlockPalette        ; getBlockPalette
  33.             dw    ?
  34. _colourCloseTo        dw    0            ; colourCloseTo
  35.             dw    ?
  36. _colourCloseToX        dw    0            ; colourCloseToX
  37.             dw    ?
  38. _imageSize        dw    0            ; imageSize
  39.             dw    ?
  40. _imageSizeDim        dw    0            ; imageSizeDim
  41.             dw    ?
  42. _setPage        dw    0            ; setPage (not implemented yet)
  43.             dw    ?
  44.  
  45. ;*** Currently active I/O functions (filled in by loadGraphDriver())
  46.             dd    20    DUP(?)
  47.  
  48. ;*** Input functions
  49. _getImage_scr        dw    0            ; getImage
  50.             dw    ?
  51. _getImage_mem        dw    0
  52.             dw    ?
  53. _getLine_scr        dw      getLine_scr              ; getLine
  54.             dw    ?
  55. _getLine_mem        dw    getLine_mem
  56.             dw    ?
  57. _getPixel_scr        dw    getPixel_scr        ; getPixel
  58.             dw    ?
  59. _getPixel_mem        dw    getPixel_mem
  60.             dw    ?
  61.  
  62. ;*** Output functions
  63. _putImage_scr_copy    dw    0            ; putImage
  64.             dw    ?
  65. _putImage_scr_and    dw    0
  66.             dw    ?
  67. _putImage_scr_not    dw    0
  68.             dw    ?
  69. _putImage_scr_or    dw    0
  70.             dw    ?
  71. _putImage_scr_xor    dw    0
  72.             dw    ?
  73. _putImage_mem_copy    dw    0
  74.             dw    ?
  75. _putImage_mem_and    dw    0
  76.             dw    ?
  77. _putImage_mem_not    dw    0
  78.             dw    ?
  79. _putImage_mem_or    dw    0
  80.             dw    ?
  81. _putImage_mem_xor    dw    0
  82.             dw    ?
  83. _putImageInv_scr_copy    dw    0            ; putImageInv
  84.             dw    ?
  85. _putImageInv_scr_and    dw    0
  86.             dw    ?
  87. _putImageInv_scr_not    dw      0
  88.             dw    ?
  89. _putImageInv_scr_or    dw      0
  90.             dw    ?
  91. _putImageInv_scr_xor    dw    0
  92.             dw    ?
  93. _putImageInv_mem_copy    dw    0
  94.             dw    ?
  95. _putImageInv_mem_and    dw    0
  96.             dw    ?
  97. _putImageInv_mem_not    dw    0
  98.             dw    ?
  99. _putImageInv_mem_or    dw    0
  100.             dw    ?
  101. _putImageInv_mem_xor    dw    0
  102.             dw    ?
  103. _putLine_scr_copy          dw    putLine_scr_copy    ; putLine
  104.             dw    ?
  105. _putLine_scr_and          dw      0
  106.             dw    ?
  107. _putLine_scr_not          dw      0
  108.             dw    ?
  109. _putLine_scr_or          dw      0
  110.             dw    ?
  111. _putLine_scr_xor          dw    0
  112.             dw    ?
  113. _putLine_mem_copy    dw      putLine_mem_copy
  114.             dw    ?
  115. _putLine_mem_and    dw      0
  116.             dw    ?
  117. _putLine_mem_not    dw      0
  118.             dw    ?
  119. _putLine_mem_or        dw      0
  120.             dw    ?
  121. _putLine_mem_xor    dw    0
  122.             dw    ?
  123. _putLineInv_scr_copy       dw    0            ; putLineInv
  124.             dw    ?
  125. _putLineInv_scr_and       dw    0
  126.             dw    ?
  127. _putLineInv_scr_not       dw    0
  128.             dw    ?
  129. _putLineInv_scr_or       dw    0
  130.             dw    ?
  131. _putLineInv_scr_xor       dw    0
  132.             dw    ?
  133. _putLineInv_mem_copy    dw    0
  134.             dw    ?
  135. _putLineInv_mem_and    dw    0
  136.             dw    ?
  137. _putLineInv_mem_not    dw    0
  138.             dw    ?
  139. _putLineInv_mem_or    dw    0
  140.             dw    ?
  141. _putLineInv_mem_xor    dw    0
  142.             dw    ?
  143. _putPixel_scr_copy    dw    putPixel_scr_copy    ; putPixel
  144.             dw    ?
  145. _putPixel_scr_and    dw      0
  146.             dw    ?
  147. _putPixel_scr_not    dw      0
  148.             dw    ?
  149. _putPixel_scr_or    dw      0
  150.             dw    ?
  151. _putPixel_scr_xor    dw    0
  152.             dw    ?
  153. _putPixel_mem_copy    dw    putPixel_mem_copy
  154.             dw    ?
  155. _putPixel_mem_and    dw      putPixel_mem_and
  156.             dw    ?
  157. _putPixel_mem_not    dw      putPixel_mem_not
  158.             dw    ?
  159. _putPixel_mem_or    dw      putPixel_mem_or
  160.             dw    ?
  161. _putPixel_mem_xor    dw    putPixel_mem_xor
  162.             dw    ?
  163. _line_scr_copy        dw    0            ; line
  164.             dw    ?
  165. _line_scr_and        dw      0
  166.             dw    ?
  167. _line_scr_not        dw      0
  168.             dw    ?
  169. _line_scr_or        dw      0
  170.             dw    ?
  171. _line_scr_xor        dw    0
  172.             dw    ?
  173. _line_mem_copy        dw    0
  174.             dw    ?
  175. _line_mem_and        dw    0
  176.             dw    ?
  177. _line_mem_not        dw    0
  178.             dw    ?
  179. _line_mem_or        dw    0
  180.             dw    ?
  181. _line_mem_xor        dw    0
  182.             dw    ?
  183. _horizLine_scr_copy    dw    horizLine_scr_copy      ; horizLine
  184.             dw    ?
  185. _horizLine_scr_and    dw      0
  186.             dw    ?
  187. _horizLine_scr_not    dw      0
  188.             dw    ?
  189. _horizLine_scr_or    dw      0
  190.             dw    ?
  191. _horizLine_scr_xor    dw    0
  192.             dw    ?
  193. _horizLine_mem_copy    dw    horizLine_mem_copy
  194.             dw    ?
  195. _horizLine_mem_and    dw      0
  196.             dw    ?
  197. _horizLine_mem_not    dw      0
  198.             dw    ?
  199. _horizLine_mem_or    dw      0
  200.             dw    ?
  201. _horizLine_mem_xor    dw    0
  202.             dw    ?
  203. _vertLine_scr_copy    dw    0             ; vertLine
  204.             dw    ?
  205. _vertLine_scr_and    dw    0
  206.             dw    ?
  207. _vertLine_scr_not    dw    0
  208.             dw    ?
  209. _vertLine_scr_or    dw    0
  210.             dw    ?
  211. _vertLine_scr_xor    dw    0
  212.             dw    ?
  213. _vertLine_mem_copy    dw    0
  214.             dw    ?
  215. _vertLine_mem_and    dw    0
  216.             dw    ?
  217. _vertLine_mem_not    dw    0
  218.             dw    ?
  219. _vertLine_mem_or    dw    0
  220.             dw    ?
  221. _vertLine_mem_xor    dw    0
  222.             dw    ?
  223. _drawRect_scr_copy    dw    0            ; drawRect
  224.             dw    ?
  225. _drawRect_scr_and    dw    0
  226.             dw    ?
  227. _drawRect_scr_not    dw    0
  228.             dw    ?
  229. _drawRect_scr_or    dw    0
  230.             dw    ?
  231. _drawRect_scr_xor    dw    0
  232.             dw    ?
  233. _drawRect_mem_copy    dw    0
  234.             dw    ?
  235. _drawRect_mem_and    dw    0
  236.             dw    ?
  237. _drawRect_mem_not    dw    0
  238.             dw    ?
  239. _drawRect_mem_or    dw    0
  240.             dw    ?
  241. _drawRect_mem_xor    dw    0
  242.             dw    ?
  243. _filledRect_scr_copy    dw    0            ; filledRect
  244.             dw    ?
  245. _filledRect_scr_and    dw      0
  246.             dw    ?
  247. _filledRect_scr_not    dw      0
  248.             dw    ?
  249. _filledRect_scr_or    dw      0
  250.             dw    ?
  251. _filledRect_scr_xor    dw    0
  252.             dw    ?
  253. _filledRect_mem_copy    dw    0
  254.             dw    ?
  255. _filledRect_mem_and    dw    0
  256.             dw    ?
  257. _filledRect_mem_not    dw    0
  258.             dw    ?
  259. _filledRect_mem_or    dw    0
  260.             dw    ?
  261. _filledRect_mem_xor    dw    0
  262.             dw    ?
  263. _clearGraphics_scr_copy    dw    clearGraphics_scr_copy    ; clearGraphics
  264.             dw    ?
  265. _clearGraphics_scr_and    dw      0
  266.             dw    ?
  267. _clearGraphics_scr_not    dw      0
  268.                   dw    ?
  269. _clearGraphics_scr_or    dw      0
  270.             dw    ?
  271. _clearGraphics_scr_xor    dw    0
  272.             dw    ?
  273. _clearGraphics_mem_copy    dw    0
  274.             dw    ?
  275. _clearGraphics_mem_and    dw    0
  276.             dw    ?
  277. _clearGraphics_mem_not    dw    0
  278.             dw    ?
  279. _clearGraphics_mem_or    dw    0
  280.             dw    ?
  281. _clearGraphics_mem_xor    dw    0
  282.             dw    ?
  283. _ellipse_scr_copy    dw    0            ; ellipse
  284.             dw    ?
  285. _ellipse_scr_and    dw    0
  286.             dw    ?
  287. _ellipse_scr_not    dw    0
  288.             dw    ?
  289. _ellipse_scr_or        dw    0
  290.             dw    ?
  291. _ellipse_scr_xor    dw    0
  292.             dw    ?
  293. _ellipse_mem_copy    dw    0
  294.             dw    ?
  295. _ellipse_mem_and    dw    0
  296.             dw    ?
  297. _ellipse_mem_not    dw    0
  298.             dw    ?
  299. _ellipse_mem_or        dw    0
  300.             dw    ?
  301. _ellipse_mem_xor    dw    0
  302.             dw    ?
  303. _filledEllipse_scr_copy    dw    0            ; filledEllipse
  304.             dw    ?
  305. _filledEllipse_scr_and    dw    0
  306.             dw    ?
  307. _filledEllipse_scr_not    dw    0
  308.             dw    ?
  309. _filledEllipse_scr_or    dw    0
  310.             dw    ?
  311. _filledEllipse_scr_xor    dw    0
  312.             dw    ?
  313. _filledEllipse_mem_copy    dw    0
  314.             dw    ?
  315. _filledEllipse_mem_and    dw    0
  316.             dw    ?
  317. _filledEllipse_mem_not    dw    0
  318.             dw    ?
  319. _filledEllipse_mem_or    dw    0
  320.             dw    ?
  321. _filledEllipse_mem_xor    dw    0
  322.             dw    ?
  323. _circle_scr_copy    dw    0            ; circle
  324.             dw    ?
  325. _circle_scr_and        dw    0
  326.             dw    ?
  327. _circle_scr_not        dw    0
  328.             dw    ?
  329. _circle_scr_or        dw    0
  330.             dw    ?
  331. _circle_scr_xor        dw    0
  332.             dw    ?
  333. _circle_mem_copy    dw    0
  334.             dw    ?
  335. _circle_mem_and        dw    0
  336.             dw    ?
  337. _circle_mem_not        dw    0
  338.             dw    ?
  339. _circle_mem_or        dw    0
  340.             dw    ?
  341. _circle_mem_xor        dw    0
  342.             dw    ?
  343. _filledCircle_scr_copy    dw    0            ; filledCircle
  344.             dw    ?
  345. _filledCircle_scr_and    dw    0
  346.             dw    ?
  347. _filledCircle_scr_not    dw    0
  348.             dw    ?
  349. _filledCircle_scr_or    dw    0
  350.             dw    ?
  351. _filledCircle_scr_xor    dw    0
  352.             dw    ?
  353. _filledCircle_mem_copy    dw    0
  354.             dw    ?
  355. _filledCircle_mem_and    dw    0
  356.             dw    ?
  357. _filledCircle_mem_not    dw    0
  358.             dw    ?
  359. _filledCircle_mem_or    dw    0
  360.             dw    ?
  361. _filledCircle_mem_xor    dw    0
  362.             dw    ?
  363. _fillRegion_scr_copy    dw    0            ; fillRegion
  364.             dw    ?
  365. _fillRegion_scr_and    dw    0
  366.             dw    ?
  367. _fillRegion_scr_not    dw    0
  368.             dw    ?
  369. _fillRegion_scr_or    dw    0
  370.             dw    ?
  371. _fillRegion_scr_xor    dw    0
  372.             dw    ?
  373. _fillRegion_mem_copy    dw    0
  374.             dw    ?
  375. _fillRegion_mem_and    dw    0
  376.             dw    ?
  377. _fillRegion_mem_not    dw    0
  378.             dw    ?
  379. _fillRegion_mem_or    dw    0
  380.             dw    ?
  381. _fillRegion_mem_xor    dw    0
  382.             dw    ?
  383. _fillLine_scr_copy    dw    0            ; fillLine
  384.             dw    ?
  385. _fillLine_scr_and    dw      0
  386.             dw    ?
  387. _fillLine_scr_not    dw      0
  388.             dw    ?
  389. _fillLine_scr_or    dw      0
  390.             dw    ?
  391. _fillLine_scr_xor    dw    0
  392.             dw    ?
  393. _fillLine_mem_copy    dw    0
  394.             dw    ?
  395. _fillLine_mem_and    dw      0
  396.             dw    ?
  397. _fillLine_mem_not    dw      0
  398.             dw    ?
  399. _fillLine_mem_or    dw      0
  400.             dw    ?
  401. _fillLine_mem_xor    dw    0
  402.             dw    ?
  403. ;*** Mode information
  404. scrnMaxX        dw    319    ; physical dimensions
  405. scrnMaxY        dw    399
  406. maxColour        dw    255    ; maximum colour number
  407. xRatio                   dw    4    ; aspect ratio 4:5 (320:400 in
  408. yRatio            dw    5    ;   lowest terms)
  409. bitsPerPixel        dw    8    ; 8 bits per pixel
  410. inMaxX            dw    319    ; current input screen dimensions
  411. inMaxY            dw    399
  412. outMaxX            dw    319    ; current output screen dimensions
  413. outMaxY            dw    399
  414. inScreenWide        dw    ?    ; needed only for virtual screens
  415. outScreenWide        dw    ?
  416. ;*** Viewport information
  417. inViewportULX        dw    0
  418. inViewportULY        dw    0
  419. inViewportLRX        dw    319
  420. inViewportLRY        dw    399
  421. outViewportULX        dw    0
  422. outViewportULY        dw    0
  423. outViewportLRX        dw    319
  424. outViewportLRY        dw    399
  425. ;*** Paging information
  426. pagingSupported        dw    ?    ; not implemented yet
  427. curPage            dw    ?    ; not implemented yet
  428. maxPage            dw    ?    ; not implemented yet
  429. ;*** Force (image width MOD imageWideAdjust) = 0.
  430. imageWideAdjust        dw    ?    ; not implemented yet
  431. ;*** Current and screen addresses
  432.     LABEL    inAddr    DWORD        ; current input address
  433. inOff    dw    0
  434. inSeg    dw    0A000h
  435.     LABEL    outAddr    DWORD        ; current output address
  436. outOff    dw    0
  437. outSeg    dw    0A000h
  438.     LABEL    scrAddr    DWORD        ; screen address
  439. scrOff    dw    0
  440. scrSeg    dw    0A000h
  441. ;*** Copyright string
  442.     db    'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
  443.  
  444.  
  445. inited        db    0
  446. colourPalette    db    768    DUP(?)
  447. lineOffs    dw    400    DUP(?)
  448.  
  449. ; Plane masks for horizLine
  450. leftEdgeMask    db    1111b, 1110b, 1100b, 1000b
  451. rightEdgeMask    db    0001b, 0011b, 0111b, 1111b
  452.  
  453.  
  454. SC_INDEX    EQU    3C4h    ; Sequence Controller Index
  455. GC_INDEX    EQU    3CEh    ; Graphics Controller Index register
  456. CRTC_INDEX    EQU    3D4h    ; CRT Controller Index
  457. MISC_OUTPUT    EQU    3C2h    ; Miscellaneous Output register
  458. MAP_MASK    EQU     02h     ; index in SC of Map Mask register
  459. READ_MAP    EQU    4    ; Read Map register index in GC
  460. MEMORY_MODE    EQU    4    ; Memory mode register in SC
  461. GRAPHICS_MODE    EQU    5    ; Graphics Mode register index in GC
  462. MISCELLANEOUS    EQU    6    ; Miscellaneous register index in GC
  463. MAX_SCAN_LINE    EQU    9          ; Maximum Scan Line reg index in CRTC
  464. START_ADDR_HIGH    EQU    0Ch    ; Start Address High reg index in CRTC
  465. UNDERLINE    EQU    14h    ; Underline Location reg index in CRTC
  466. MODE_CONTROL    EQU    17h    ; Mode Control register index in CRTC
  467. INPUT_STATUS_1  EQU     03DAh   ; Input Status 1 register
  468. START_ADDR_HIGH EQU    0Ch     ; start address high byte
  469. START_ADDR_LOW  EQU    0Dh     ; start address low byte
  470. WORD_OUTS_OK    EQU    1    ; Set to 0 for VGAs that can't handle
  471.                 ; word OUTs to indexed VGA registers
  472.  
  473.  
  474. MACRO    OUT_WORD
  475. if WORD_OUTS_OK
  476.   out    dx,ax
  477. else
  478.   out    dx,al
  479.   inc    dx
  480.   xchg    ah,al
  481.   out    dx,al
  482.   dec    dx
  483.   xchg    ah,al
  484. endif
  485. ENDM
  486.  
  487. MACRO    CONSTANT_TO_INDEXED_REG ADDRESS, INDEX, VALUE
  488.   mov    dx,ADDRESS
  489.   mov    ax,(VALUE shl 8) + INDEX
  490.   OUT_WORD
  491. ENDM
  492.  
  493.  
  494. ;*****
  495. ;***** initGraphics
  496. ;*****
  497.  
  498. PROC    C    initGraphics
  499.   mov    ax,0013h            ; set mode 13h
  500.   int    10h
  501.  
  502.   ; change CPU addressing to linear
  503.   mov    dx,SC_INDEX
  504.   mov    al,MEMORY_MODE
  505.   out    dx,al
  506.   inc    dx
  507.   in    al,dx
  508.   and    al,NOT 08h            ; turn off chain 4
  509.   or     al,04h                ; turn off odd/even
  510.   out    dx,al
  511.   mov    dx,GC_INDEX
  512.   mov    al,GRAPHICS_MODE
  513.   out    dx,al
  514.   inc    dx
  515.   in    al,dx
  516.   and    al,NOT 10h            ; turn off odd/even
  517.   out    dx,al
  518.   dec    dx
  519.   mov    al,MISCELLANEOUS
  520.   out    dx,al
  521.   inc    dx
  522.   in    al,dx
  523.   and    al,NOT 02h            ; turn off chain
  524.   out    dx,al
  525.  
  526.   ; clear all 256k of video RAM
  527.   CONSTANT_TO_INDEXED_REG SC_INDEX, MAP_MASK, 0Fh    ; enable writes to all planes
  528.   mov    ax,0A000h
  529.   mov    es,ax
  530.   xor    di,di
  531.   mov    ax,di
  532.   mov    cx,8000h            ; # of words in 64k
  533.   cld
  534.   rep    stosw                ; clear all of display RAM
  535.  
  536.   ; Tweak the mode to 320x400 by not scanning each line twice
  537.   mov    dx,CRTC_INDEX
  538.   mov    al,MAX_SCAN_LINE
  539.   out    dx,al
  540.   inc    dx
  541.   in    al,dx
  542.   and    al,NOT 1Fh            ; set max scan line to 0
  543.   out    dx,al
  544.   dec    dx
  545.  
  546.   ; Change CRTC scanning from DWORD to BYTE mode, allowing the CRTC to scan
  547.   ; more than 64k of video data.
  548.   mov    al,UNDERLINE
  549.   out    dx,al
  550.   inc    dx
  551.   in    al,dx
  552.   and    al,NOT 40h            ; turn off doubleword
  553.   out    dx,al
  554.   dec    dx
  555.   mov    al,MODE_CONTROL
  556.   out    dx,al
  557.   inc    dx
  558.   in    al,dx
  559.   or    al,40h                ; turn on byte mode bit
  560.   out    dx,al
  561.  
  562.   mov    al,[inited]            ; restore palette if necessary
  563.   or    al,al
  564.   jz    @@notInited
  565.   mov    ax,1
  566.   retf
  567.  
  568.     @@notInited:
  569.   mov    [inited],1
  570.   push    si
  571.   mov    si,OFFSET lineOffs
  572.   mov    cx,SCREEN_DEEP
  573.   xor    bx,bx
  574.  
  575.     @@LLoop:
  576.   mov    ax,SCREEN_WIDE/4
  577.   mul    bx
  578.   mov    [cs:si],ax
  579.   add    si,2
  580.   inc    bx
  581.   loop    @@LLoop
  582.   pop    si
  583.   mov    ax,1
  584.   retf
  585. ENDP
  586.  
  587.  
  588. ;*****
  589. ;***** putLine
  590. ;*****
  591.  
  592. PROC    C    putLine_scr_copy
  593.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  594.         LOCAL    x2:WORD
  595.   push    ds si di
  596.  
  597.   mov    bx,[lineNum]            ; start address in ES:DI
  598.   shl    bx,1
  599.   mov    di,[lineOffs+bx]
  600.   mov    dx,[xOff]
  601.   shr    dx,2
  602.   add    di,dx
  603.   mov    ax,0A000h
  604.   mov    es,ax
  605.   lds    si,[buf]            ; source in DS:SI
  606.   cld
  607.  
  608.   mov    bx,[xOff]
  609.   add    bx,[lineLen]            ; calculate x2
  610.   dec    bx
  611.   mov    [x2],bx
  612.  
  613.   mov    cx,[lineLen]            ; line is short
  614.   cmp    cx,4
  615. JUMPS
  616.   jle    @@ShortLine
  617. NOJUMPS
  618.  
  619.   mov    cx,[xOff]            ; calculate starting plane
  620.   mov    bx,cx
  621.   mov    ax,0102h
  622.   and    cl,3
  623.   shl    ah,cl
  624.   mov    dx,SC_INDEX
  625.   OUT_WORD
  626.   push    si
  627.   mov    bx,[x2]
  628.   mov    cx,[xOff]
  629.       @@Loop1:
  630.   cmp    cx,bx
  631.   jg    @@Loop1Done
  632.   lodsb
  633.   stosb
  634.   add    cx,4
  635.   add    si,3
  636.   jmp    short    @@Loop1
  637.  
  638.     @@Loop1Done:
  639.   pop    si
  640.   inc    si
  641.   push    si
  642.   mov    bx,[xOff]
  643.   inc    bx
  644.   mov    cx,bx
  645.   mov    ax,0102h
  646.   and    cl,3
  647.   shl    ah,cl
  648.   mov    dx,SC_INDEX
  649.   OUT_WORD
  650.   mov    cx,bx
  651.   mov    bx,[lineNum]            ; start address in ES:DI
  652.   shl    bx,1
  653.   mov    di,[lineOffs+bx]
  654.   shr    cx,2
  655.   add    di,cx
  656.   mov    bx,[x2]
  657.   mov    cx,[xOff]
  658.   inc    cx
  659.     @@Loop2:
  660.   cmp    cx,bx
  661.   jg    @@Loop2Done
  662.   lodsb
  663.   stosb
  664.   add    cx,4
  665.   add    si,3
  666.   jmp    short    @@Loop2
  667.  
  668.       @@Loop2Done:
  669.   pop    si
  670.   inc    si
  671.   push    si
  672.   mov    bx,[xOff]
  673.   add    bx,2
  674.   mov    cx,bx
  675.   mov    ax,0102h
  676.   and    cl,3
  677.   shl    ah,cl
  678.   mov    dx,SC_INDEX
  679.   OUT_WORD
  680.   mov    cx,bx
  681.   mov    bx,[lineNum]
  682.   shl    bx,1
  683.   mov    di,[lineOffs+bx]
  684.   shr    cx,2
  685.   add    di,cx
  686.   mov    bx,[x2]
  687.   mov    cx,[xOff]
  688.   add    cx,2
  689.       @@Loop3:
  690.   cmp    cx,bx
  691.   jg    @@Loop3Done
  692.   lodsb
  693.   stosb
  694.   add    cx,4
  695.   add    si,3
  696.   jmp    short    @@Loop3
  697.  
  698.       @@Loop3Done:
  699.   pop    si
  700.   inc    si
  701.   mov    bx,[xOff]
  702.   add    bx,3
  703.   mov    cx,bx
  704.   mov    ax,0102h
  705.   and    cl,3
  706.   shl    ah,cl
  707.   mov    dx,SC_INDEX
  708.   OUT_WORD
  709.   mov    cx,bx
  710.   mov    bx,[lineNum]
  711.   shl    bx,1
  712.   mov    di,[lineOffs+bx]
  713.   shr    cx,2
  714.   add    di,cx
  715.   mov    bx,[x2]
  716.   mov    cx,[xOff]
  717.   add    cx,3
  718.     @@Loop4:
  719.   cmp    cx,bx
  720.   jg    @@Exit
  721.   lodsb
  722.   stosb
  723.   add    cx,4
  724.   add    si,3
  725.   jmp    short    @@Loop4
  726.  
  727.       @@ShortLine:
  728.   mov    cx,[xOff]
  729.   mov    bx,cx
  730.   and    cl,3
  731.   mov    ax,0102h
  732.   shl    ah,cl
  733.   mov    dx,SC_INDEX
  734.   OUT_WORD
  735.   mov    cx,bx
  736.   shr    bx,2
  737.   mov    di,bx
  738.   mov    bx,[lineNum]
  739.   shl    bx,1
  740.   add    di,[lineOffs+bx]
  741.   movsb
  742.   cmp    cx,[x2]
  743.   jge    @@Exit
  744.   inc    [xOff]
  745.   jmp    short    @@ShortLine
  746.  
  747.       @@Exit:
  748.   pop   di si ds
  749.   leave
  750.   retf
  751. ENDP
  752.  
  753. PROC    C    putLine_mem_copy
  754.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  755.   push    ds si di            ; save these registers
  756.  
  757.   xor    eax,eax                ; clear EAX
  758.   xor    edx,edx                ; clear EDX
  759.   xor    edi,edi                ; clear EDI
  760.  
  761.   les    di,[outAddr]            ; load output address
  762.   mov    ax,[y]
  763.   mov    dx,[outScreenWide]
  764.   mul    edx                    ; EDX:EAX = offset - EDI - x
  765.   add    edi,eax                ; EDI = offset - x
  766.   mov    dx,[xOff]
  767.   add    edi,edx                ; EDI = offset
  768.   mov    edx,edi                ; EDX = offset
  769.   shr    edx,4                ; EDX = # of paragraphs (segments)
  770.   add    dx,[outSeg]            ; DX = new segment
  771.   mov    es,dx                ; ES = new segment
  772.   and    di,0000000000001111b             ; DI = offset within new segment
  773.  
  774.   lds    si,[buf]            ; load input address
  775.   mov    dx,si                ; DX = offset
  776.   shr    dx,4                ; DX = # of paragraphs (segments)
  777.   mov    ax,ds                ; AX = DS
  778.   add    ax,dx                ; AX = new DS
  779.   mov    ds,ax                ; DS = new DS
  780.   and    si,0000000000001111b        ; SI = offset within new segment
  781.  
  782.   cld
  783.   mov    cx,[lineLen]            ; CX = line length
  784.   mov    dx,cx                ; DX = line length
  785.   shr    cx,2                ; CX = line length in dwords
  786.   rep    movsd                     ; move the dwords if necessary
  787.   mov    cx,dx                ; CX = line length in bytes
  788.   and    cx,0000000000000011b        ; CX = any residual bytes
  789.   rep    movsb                ; move the bytes if necessary
  790.  
  791.   pop    di si ds            ; restore registers
  792.   leave                    ; clean up
  793.   retf                    ; return
  794. ENDP
  795.  
  796.  
  797. ;*****
  798. ;***** getLine
  799. ;*****
  800.  
  801. PROC    C    getLine_scr
  802.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  803.     LOCAL    x2:WORD
  804.   push    ds si di
  805.  
  806.   mov    bx,[lineNum]            ; start address in ES:DI
  807.   shl    bx,1
  808.   mov    si,[lineOffs+bx]
  809.   mov    dx,[xOff]
  810.   shr    dx,2
  811.   add    si,dx
  812.   mov    ax,0A000h
  813.   mov    ds,ax
  814.   les    di,[buf]            ; buffer addr in DS:SI
  815.   cld
  816.  
  817.   mov    bx,[xOff]
  818.   add    bx,[lineLen]            ; calculate x2
  819.   dec    bx
  820.   mov    [x2],bx
  821.  
  822.   mov    cx,[lineLen]            ; line is short
  823.   cmp    cx,4
  824. JUMPS
  825.   jle    @@ShortLine
  826. NOJUMPS
  827.  
  828.   mov    ax,[xOff]            ; calculate starting plane
  829.   mov    bx,ax
  830.   and    al,3
  831.   mov    ah,al
  832.   mov    al,READ_MAP
  833.   mov    dx,GC_INDEX
  834.   OUT_WORD
  835.   push    di
  836.   mov    bx,[x2]
  837.   mov    cx,[xOff]
  838.     @@Loop1:
  839.   cmp    cx,bx
  840.   jg    @@Loop1Done
  841.   lodsb
  842.   stosb
  843.   add    cx,4
  844.   add    di,3
  845.   jmp    short    @@Loop1
  846.  
  847.     @@Loop1Done:
  848.   pop    di
  849.   inc    di
  850.   push    di
  851.   mov    bx,[xOff]
  852.   inc    bx
  853.   mov    ax,bx
  854.   and    al,3
  855.   mov    ah,al
  856.   mov    al,READ_MAP
  857.   mov    dx,GC_INDEX
  858.   OUT_WORD
  859.   mov    cx,bx
  860.   mov    bx,[lineNum]            ; start address in ES:DI
  861.   shl    bx,1
  862.   mov    si,[lineOffs+bx]
  863.   shr    cx,2
  864.   add    si,cx
  865.   mov    bx,[x2]
  866.   mov    cx,[xOff]
  867.   inc    cx
  868.     @@Loop2:
  869.   cmp    cx,bx
  870.   jg    @@Loop2Done
  871.   lodsb
  872.   stosb
  873.   add    cx,4
  874.   add    di,3
  875.   jmp    short    @@Loop2
  876.  
  877.     @@Loop2Done:
  878.   pop    di
  879.   inc    di
  880.   push    di
  881.   mov    bx,[xOff]
  882.   add    bx,2
  883.   mov    ax,bx
  884.   and    al,3
  885.   mov    ah,al
  886.   mov    al,READ_MAP
  887.   mov    dx,GC_INDEX
  888.   OUT_WORD
  889.   mov    cx,bx
  890.   mov    bx,[lineNum]
  891.   shl    bx,1
  892.   mov    si,[lineOffs+bx]
  893.   shr    cx,2
  894.   add    si,cx
  895.   mov    bx,[x2]
  896.   mov    cx,[xOff]
  897.   add    cx,2
  898.     @@Loop3:
  899.   cmp    cx,bx
  900.   jg    @@Loop3Done
  901.   lodsb
  902.   stosb
  903.   add    cx,4
  904.   add    di,3
  905.   jmp    short    @@Loop3
  906.  
  907.     @@Loop3Done:
  908.   pop    di
  909.   inc    di
  910.   mov    bx,[xOff]
  911.   add    bx,3
  912.   mov    ax,bx
  913.   and    al,3
  914.   mov    ah,al
  915.   mov    al,READ_MAP
  916.   mov    dx,GC_INDEX
  917.   OUT_WORD
  918.   mov    cx,bx
  919.   mov    bx,[lineNum]
  920.   shl    bx,1
  921.   mov    si,[lineOffs+bx]
  922.   shr    cx,2
  923.   add    si,cx
  924.   mov    bx,[x2]
  925.   mov    cx,[xOff]
  926.   add    cx,3
  927.     @@Loop4:
  928.   cmp    cx,bx
  929.   jg    @@Exit
  930.   lodsb
  931.   stosb
  932.   add    cx,4
  933.   add    di,3
  934.   jmp    short    @@Loop4
  935.  
  936.     @@ShortLine:
  937.   mov    ax,[xOff]
  938.   mov    bx,ax
  939.   and    al,3
  940.   mov    ah,al
  941.   mov    al,READ_MAP
  942.   mov    dx,GC_INDEX
  943.   OUT_WORD
  944.   mov    cx,bx
  945.   shr    bx,2
  946.   mov    si,bx
  947.   mov    bx,[lineNum]
  948.   shl    bx,1
  949.   add    si,[lineOffs+bx]
  950.   movsb
  951.   cmp    cx,[x2]
  952.   jge    @@Exit
  953.   inc    [xOff]
  954.   jmp    short    @@ShortLine
  955.  
  956.     @@Exit:
  957.   pop   di si ds
  958.   leave
  959.   retf
  960. ENDP
  961.  
  962. PROC    C    getLine_mem
  963.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  964.   push    ds si di            ; save these registers
  965.  
  966.   xor    eax,eax                ; clear EAX
  967.   xor    edx,edx                ; clear EDX
  968.   xor    esi,esi                ; clear ESI
  969.  
  970.   les    si,[inAddr]            ; load input address
  971.   mov    ax,[y]
  972.   mov    dx,[inScreenWide]
  973.   mul    edx                    ; EDX:EAX = offset - ESI - x
  974.   add    esi,eax                ; ESI = offset - x
  975.   mov    dx,[xOff]
  976.   add    esi,edx                ; ESI = offset
  977.   mov    edx,esi                ; EDX = offset
  978.   shr    edx,4                ; EDX = # of paragraphs (segments)
  979.   add    dx,[inSeg]            ; DX = new segment
  980.   mov    ds,dx                ; ES = new segment
  981.   and    si,0000000000001111b             ; SI = offset within new segment
  982.  
  983.   les    di,[buf]            ; load output address
  984.   mov    dx,di                ; DX = offset
  985.   shr    dx,4                ; DX = # of paragraphs (segments)
  986.   mov    ax,es                ; AX = ES
  987.   add    ax,dx                ; AX = new ES
  988.   mov    es,ax                ; ES = new ES
  989.   and    di,0000000000001111b        ; DI = offset within new segment
  990.  
  991.   cld
  992.   mov    cx,[lineLen]            ; CX = line length
  993.   mov    dx,cx                ; DX = line length
  994.   shr    cx,2                ; CX = line length in dwords
  995.   rep    movsd                     ; move the dwords if necessary
  996.   mov    cx,dx                ; CX = line length in bytes
  997.   and    cx,0000000000000011b        ; CX = any residual bytes
  998.   rep    movsb                ; move the bytes if necessary
  999.  
  1000.   pop    di si ds            ; restore registers
  1001.   leave                    ; clean up
  1002.   retf                    ; return
  1003. ENDP
  1004.  
  1005.  
  1006. ;*****
  1007. ;***** putPixel
  1008. ;*****
  1009.  
  1010. ; Copy a pixel to the screen
  1011. PROC    C    putPixel_scr_copy
  1012.     ARG    x:WORD, y:WORD, colour:BYTE
  1013.   push    di
  1014.  
  1015.   mov    ax,0A000h
  1016.   mov    es,ax
  1017.   mov    bx,[y]                ; point to start of desired row
  1018.   shl    bx,1
  1019.   mov    bx,[lineOffs+bx]
  1020.   mov    dx,[x]
  1021.   mov    cx,dx                ; store x coord
  1022.   shr    dx,2
  1023.   add    bx,dx
  1024.   mov    di,bx                ; ES:DI points to pixel
  1025.   and    cl,3                ; get the plane # of the pixel
  1026.   mov    ax,102h
  1027.   shl    ah,cl                ; set the bit corresponding to plane
  1028.   mov    dx,SC_INDEX
  1029.   OUT_WORD
  1030.   mov    bl,[colour]
  1031.   mov    [es:di],bl
  1032.  
  1033.   pop    di
  1034.   leave
  1035.   retf
  1036. ENDP
  1037.  
  1038. ; Copy a pixel to memory
  1039. PROC    C    putPixel_mem_copy
  1040.     ARG    x:WORD,y:WORD,colour:BYTE
  1041.   xor    eax,eax                ; clear EAX
  1042.   xor    ebx,ebx                ; clear EBX
  1043.   xor    edx,edx                ; clear EDX
  1044.  
  1045.   les    bx,[outAddr]            ; load output address
  1046.   mov    ax,[y]
  1047.   mov    dx,[outScreenWide]
  1048.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1049.   add    ebx,eax                ; EBX = offset - x
  1050.   mov    dx,[x]
  1051.   add    ebx,edx                ; EBX = offset
  1052.  
  1053.   mov    edx,ebx                ; EDX = offset
  1054.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1055.   add    dx,[outSeg]            ; DX = new segment
  1056.   mov    es,dx                ; ES = new segment
  1057.   and    bx,0000000000001111b             ; BX = offset within new segment
  1058.  
  1059.   mov    al,[colour]            ; colour in AL
  1060.   mov    [es:bx],al            ; store pixel
  1061.   leave                    ; clean up
  1062.   retf                    ; return
  1063. ENDP
  1064.  
  1065. ; AND a pixel to memory
  1066. PROC    C    putPixel_mem_and
  1067.     ARG    x:WORD,y:WORD,colour:BYTE
  1068.   xor    eax,eax                ; clear EAX
  1069.   xor    ebx,ebx                ; clear EBX
  1070.   xor    edx,edx                ; clear EDX
  1071.  
  1072.   les    bx,[outAddr]            ; load output address
  1073.   mov    ax,[y]
  1074.   mov    dx,[outScreenWide]
  1075.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1076.   add    ebx,eax                ; EBX = offset - x
  1077.   mov    dx,[x]
  1078.   add    ebx,edx                ; EBX = offset
  1079.  
  1080.   mov    edx,ebx                ; EDX = offset
  1081.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1082.   add    dx,[outSeg]            ; DX = new segment
  1083.   mov    es,dx                ; ES = new segment
  1084.   and    bx,0000000000001111b             ; BX = offset within new segment
  1085.  
  1086.   mov    al,[colour]            ; colour in AL
  1087.   and    [es:bx],al            ; AND pixel
  1088.   leave                    ; clean up
  1089.   retf                    ; return
  1090. ENDP
  1091.  
  1092. ; NOT a pixel to memory
  1093. PROC    C    putPixel_mem_not
  1094.     ARG    x:WORD,y:WORD,colour:BYTE
  1095.   xor    eax,eax                ; clear EAX
  1096.   xor    ebx,ebx                ; clear EBX
  1097.   xor    edx,edx                ; clear EDX
  1098.  
  1099.   les    bx,[outAddr]            ; load output address
  1100.   mov    ax,[y]
  1101.   mov    dx,[outScreenWide]
  1102.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1103.   add    ebx,eax                ; EBX = offset - x
  1104.   mov    dx,[x]
  1105.   add    ebx,edx                ; EBX = offset
  1106.  
  1107.   mov    edx,ebx                ; EDX = offset
  1108.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1109.   add    dx,[outSeg]            ; DX = new segment
  1110.   mov    es,dx                ; ES = new segment
  1111.   and    bx,0000000000001111b             ; BX = offset within new segment
  1112.  
  1113.   mov    al,[colour]            ; colour in AL
  1114.   not    al                ; NOT it
  1115.   mov    [es:bx],al            ; store NOTed pixel
  1116.   leave                    ; clean up
  1117.   retf                    ; return
  1118. ENDP
  1119.  
  1120. ; OR a pixel to memory
  1121. PROC    C    putPixel_mem_or
  1122.     ARG    x:WORD,y:WORD,colour:BYTE
  1123.   xor    eax,eax                ; clear EAX
  1124.   xor    ebx,ebx                ; clear EBX
  1125.   xor    edx,edx                ; clear EDX
  1126.  
  1127.   les    bx,[outAddr]            ; load output address
  1128.   mov    ax,[y]
  1129.   mov    dx,[outScreenWide]
  1130.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1131.   add    ebx,eax                ; EBX = offset - x
  1132.   mov    dx,[x]
  1133.   add    ebx,edx                ; EBX = offset
  1134.  
  1135.   mov    edx,ebx                ; EDX = offset
  1136.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1137.   add    dx,[outSeg]            ; DX = new segment
  1138.   mov    es,dx                ; ES = new segment
  1139.   and    bx,0000000000001111b             ; BX = offset within new segment
  1140.  
  1141.   mov    al,[colour]            ; colour in AL
  1142.   or    [es:bx],al            ; OR pixel
  1143.   leave                    ; clean up
  1144.   retf                    ; return
  1145. ENDP
  1146.  
  1147. ; XOR a pixel to memory
  1148. PROC    C    putPixel_mem_xor
  1149.     ARG    x:WORD,y:WORD,colour:BYTE
  1150.   xor    eax,eax                ; clear EAX
  1151.   xor    ebx,ebx                ; clear EBX
  1152.   xor    edx,edx                ; clear EDX
  1153.  
  1154.   les    bx,[outAddr]            ; load output address
  1155.   mov    ax,[y]
  1156.   mov    dx,[outScreenWide]
  1157.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1158.   add    ebx,eax                ; EBX = offset - x
  1159.   mov    dx,[x]
  1160.   add    ebx,edx                ; EBX = offset
  1161.  
  1162.   mov    edx,ebx                ; EDX = offset
  1163.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1164.   add    dx,[outSeg]            ; DX = new segment
  1165.   mov    es,dx                ; ES = new segment
  1166.   and    bx,0000000000001111b             ; BX = offset within new segment
  1167.  
  1168.   mov    al,[colour]            ; colour in AL
  1169.   xor    [es:bx],al            ; XOR pixel
  1170.   leave                    ; clean up
  1171.   retf                    ; return
  1172. ENDP
  1173.  
  1174.  
  1175. ;*****
  1176. ;***** getPixel
  1177. ;*****
  1178.  
  1179. ; Get a pixel from the screen
  1180. PROC    C    getPixel_scr
  1181.     ARG    x:WORD, y:WORD
  1182.   push    di
  1183.  
  1184.   mov    ax,0A000h
  1185.   mov    es,ax
  1186.   mov    bx,[y]                ; point to start of desired row
  1187.   shl    bx,1
  1188.   mov    bx,[lineOffs+bx]
  1189.   mov    dx,[x]
  1190.   mov    cx,dx                ; store x coord
  1191.   shr    dx,2
  1192.   add    bx,dx
  1193.   mov    di,bx                ; ES:DI points to pixel
  1194.   and    cl,3                ; get the plane # of the pixel
  1195.   mov    al,READ_MAP
  1196.   mov    ah,cl
  1197.   mov    dx,GC_INDEX            ; set the bit corresponding to plane
  1198.   OUT_WORD
  1199.   xor    ax,ax
  1200.   mov    al,[es:di]
  1201.  
  1202.   pop    di
  1203.   leave
  1204.   retf
  1205. ENDP
  1206.  
  1207. ; Get a pixel from memory
  1208. PROC    C    getPixel_mem
  1209.     ARG    x:WORD,y:WORD
  1210.   xor    eax,eax                ; clear EAX
  1211.   xor    ebx,ebx                ; clear EBX
  1212.   xor    edx,edx                ; clear EDX
  1213.  
  1214.   les    bx,[inAddr]            ; load input address
  1215.   mov    ax,[y]
  1216.   mov    dx,[inScreenWide]
  1217.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1218.   add    ebx,eax                ; EBX = offset - x
  1219.   mov    dx,[x]
  1220.   add    ebx,edx                ; EBX = offset
  1221.  
  1222.   mov    edx,ebx                ; EDX = offset
  1223.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1224.   add    dx,[inSeg]            ; DX = new segment
  1225.   mov    es,dx                ; ES = new segment
  1226.   and    bx,0000000000001111b             ; BX = offset within new segment
  1227.  
  1228.   xor    ax,ax                ; clear AX
  1229.   mov    al,[es:bx]            ; store pixel in AX for return
  1230.   leave                    ; clean up
  1231.   retf                    ; return
  1232. ENDP
  1233.  
  1234.  
  1235. ;*****
  1236. ;***** horizLine
  1237. ;*****
  1238.  
  1239. PROC    C    horizLine_scr_copy
  1240.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1241.     LOCAL    adj1:WORD, adj2:WORD
  1242.   push    si di
  1243.   cld
  1244.  
  1245.   mov    ax,[x1]                ; set up adj1
  1246.   and    ax,3
  1247.   jz    @@adj1A
  1248.   mov    bx,4
  1249.   sub    bx,ax
  1250.   mov    ax,[x1]
  1251.   add    ax,bx
  1252.   mov    [adj1],ax
  1253.   jmp    short    @@adj1B
  1254.     @@adj1A:
  1255.   mov    ax,[x1]
  1256.   mov    [adj1],ax
  1257.     @@adj1B:
  1258.  
  1259.   mov    ax,[x2]                ; set up adj2
  1260.   mov    [adj2],ax
  1261.   and    ax,3
  1262.   sub    [adj2],ax
  1263.  
  1264.   mov    ax,[x1]                ; ensure x1 <= x2
  1265.   cmp    ax,[x2]
  1266.   jbe    @@setup
  1267.   mov    bx,[x2]
  1268.   mov    [x1],bx
  1269.   mov    [x2],ax
  1270.  
  1271.     @@setup:
  1272.   mov    ax,0A000h            ; set ES:DI to line start address
  1273.   mov    es,ax
  1274.   mov    bx,[y]
  1275.   shl    bx,1
  1276.   mov    di,[lineOffs+bx]
  1277.   mov    bx,[x1]                ; current x counter
  1278.   shr    bx,2
  1279.   add    di,bx
  1280.  
  1281.   mov    cx,[adj2]            ; CX = # of 4-pixel sets starting
  1282.   shr    cx,2                            ; on plane 0
  1283.   mov    bx,[adj1]
  1284.   shr    bx,2
  1285.   sub    cx,bx
  1286.  
  1287.   cmp    cx,1
  1288.   jl    @@shortLine
  1289.  
  1290.   ; Draw the left edge
  1291.   mov    ax,[x1]                ; get plane number of pixel #1
  1292.   and    ax,3
  1293.   jz    @@planeZeroStart        ; starts at plane zero
  1294.   mov    si,ax                ; set for pixels
  1295.   mov    ah,[leftEdgeMask+si]
  1296.   mov    al,MAP_MASK
  1297.   mov    dx,SC_INDEX
  1298.   OUT_WORD
  1299.   mov    al,[colour]
  1300.   stosb
  1301.  
  1302.   ; Draw the interior stretch
  1303.     @@planeZeroStart:
  1304.   mov    ax,0F02h            ; enable writes to all planes
  1305.   mov    dx,SC_INDEX
  1306.   OUT_WORD
  1307.   mov    al,[colour]
  1308.   mov    ah,al
  1309.   shr    cx,1
  1310.   jc    @@Odd
  1311.   rep    stosw                ; even number of pixels
  1312.   jmp    short    @@rightEdge
  1313.     @@Odd:
  1314.   rep    stosw                ; odd number of pixels
  1315.   stosb
  1316.  
  1317.   ; Draw the right edge
  1318.     @@rightEdge:
  1319.   mov    ax,[x2]                ; get plane number of last pixel
  1320.   and    ax,3
  1321.   mov    si,ax                ; set for pixels
  1322.   mov    ah,[rightEdgeMask+si]
  1323.   mov    al,MAP_MASK
  1324.   mov    dx,SC_INDEX
  1325.   OUT_WORD
  1326.   mov    al,[colour]
  1327.   stosb
  1328.  
  1329.     @@Exit:
  1330.   pop    di si                ; clean up and go home
  1331.   leave
  1332.   retf
  1333.  
  1334.     @@shortLine:            ; for very small lines
  1335.   mov    al,[colour]
  1336.   mov    cx,[x1]
  1337.   mov    dx,[y]
  1338.     @@Loop:
  1339.   push    ax cx dx            ; slow loop until done
  1340.   call    putPixel_scr_copy C, cx, dx, ax
  1341.   pop    dx cx ax
  1342.   inc    cx
  1343.   cmp    cx,[x2]
  1344.   jle    @@Loop
  1345.  
  1346.   pop     di si
  1347.   leave
  1348.   retf
  1349. ENDP
  1350.  
  1351. PROC    C    horizLine_mem_copy
  1352.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1353.   push    edi                ; store EDI
  1354.  
  1355.   xor    eax,eax                ; clear EAX
  1356.   xor    edi,edi                ; clear EDI
  1357.   xor    edx,edx                ; clear EDX
  1358.  
  1359.   les    di,[outAddr]            ; load output address
  1360.   mov    ax,[y]
  1361.   mov    dx,[outScreenWide]
  1362.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1363.   add    edi,eax                ; EDI = offset - x
  1364.   mov    dx,[x1]
  1365.   add    edi,edx                ; EDI = offset
  1366.   mov    edx,edi                ; EDX = offset
  1367.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1368.   add    dx,[outSeg]            ; DX = new segment
  1369.   mov    es,dx                ; ES = new segment
  1370.   and    di,0000000000001111b             ; DI = offset within new segment
  1371.  
  1372.   mov    al,[colour]            ; colour in AL
  1373.   mov    ah,al                ; colour in AH
  1374.   mov    bx,ax
  1375.   shl    eax,16
  1376.   mov    ax,bx                 ; colour in each byte of EAX
  1377.  
  1378.   mov    cx,[x2]
  1379.   sub    cx,[x1]
  1380.   inc    cx                ; CX = line length in pixels
  1381.   mov    dx,cx                ; DX = line length in bytes
  1382.  
  1383.   shr    cx,2                ; CX = line length in dwords
  1384.   rep    stosd                ; store four bytes at a time
  1385.   mov    cx,dx                ; CX = line length in pixels
  1386.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1387.   rep    stosb                ; store the remaining bytes
  1388.  
  1389.   pop    edi                    ; restore EDI
  1390.   leave                    ; clean up
  1391.   retf                    ; return
  1392. ENDP
  1393.  
  1394.  
  1395. ;*****
  1396. ;***** setPaletteReg
  1397. ;*****
  1398.  
  1399. PROC    C    setPaletteReg
  1400.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1401.   mov    bx,[palNum]
  1402.  
  1403.   mov    dx,3C8h                ; set for the right palette register
  1404.   mov    ax,[palNum]
  1405.   out    dx,al
  1406.   inc    dx
  1407.  
  1408.   mov    al,[red]            ; red
  1409.   shr    al,2
  1410.   jnc    @@L1
  1411.   cmp    al,63
  1412.   je    @@L1
  1413.   inc    al
  1414.     @@L1:
  1415.   out    dx,al
  1416.  
  1417.   mov    al,[green]            ; green
  1418.   shr    al,2
  1419.   jnc    @@L2
  1420.   cmp    al,63
  1421.   je    @@L2
  1422.   inc    al
  1423.     @@L2:
  1424.   out    dx,al
  1425.  
  1426.   mov    al,[blue]            ; blue
  1427.   shr    al,2
  1428.   jnc    @@L3
  1429.   cmp    al,63
  1430.   je    @@L3
  1431.   inc    al
  1432.     @@L3:
  1433.   out    dx,al
  1434.  
  1435.   leave
  1436.   retf
  1437. ENDP
  1438.  
  1439.  
  1440. ;*****
  1441. ;***** getPaletteReg
  1442. ;*****
  1443.  
  1444. PROC    C    getPaletteReg
  1445.     ARG    palNum:WORD,red:DATAPTR,green:DATAPTR,blue:DATAPTR
  1446.   push    ds si
  1447.  
  1448.   mov    dx,3C7h                ; set for right palette register
  1449.   mov    ax,[palNum]
  1450.   out    dx,al
  1451.   mov    dx,3C9h
  1452.  
  1453.   in    al,dx                ; red
  1454.   lds    si,[red]
  1455.   shl    al,2
  1456.   mov    [ds:si],al
  1457.   in    al,dx                ; green
  1458.   lds    si,[green]
  1459.   shl    al,2
  1460.   mov    [ds:si],al
  1461.   in    al,dx                ; blue
  1462.   lds    si,[blue]
  1463.   shl    al,2
  1464.   mov    [ds:si],al
  1465.  
  1466.   pop    si ds
  1467.   leave
  1468.   retf
  1469. ENDP
  1470.  
  1471.  
  1472. ;*****
  1473. ;***** setBlockPalette
  1474. ;*****
  1475.  
  1476. PROC    C    setBlockPalette
  1477.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1478.   push    ds si
  1479.  
  1480.   lds    si,[paletteData]        ; set up
  1481.   mov    dx,3C8h
  1482.   mov    ax,[firstReg]
  1483.   out    dx,al
  1484.   inc    dx
  1485.   mov    cx,[lastReg]            ; CX = number of registers
  1486.   sub    cx,ax
  1487.   inc    cx
  1488.   cld
  1489.  
  1490.     @@LLoop:
  1491.   lodsb            ; red
  1492.   shr    al,2
  1493.   jnc    @@L1
  1494.   cmp    al,63
  1495.   je    @@L1
  1496.   inc    al
  1497.       @@L1:
  1498.   out    dx,al
  1499.  
  1500.   lodsb            ; green
  1501.   shr    al,2
  1502.   jnc    @@L2
  1503.   cmp    al,63
  1504.   je    @@L2
  1505.   inc    al
  1506.       @@L2:
  1507.   out    dx,al
  1508.  
  1509.   lodsb            ; blue
  1510.   shr    al,2
  1511.   jnc    @@L3
  1512.   cmp    al,63
  1513.   je    @@L3
  1514.   inc    al
  1515.       @@L3:
  1516.   out    dx,al
  1517.  
  1518.   loop    @@LLoop
  1519.  
  1520.     @@LExit:
  1521.   pop    si ds
  1522.   leave
  1523.   retf
  1524. ENDP
  1525.  
  1526.  
  1527. ;*****
  1528. ;***** getBlockPalette
  1529. ;*****
  1530.  
  1531. PROC    C    getBlockPalette
  1532.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1533.   push    di
  1534.  
  1535.   les    di,[paletteData]        ; set up
  1536.   mov    dx,3C7h
  1537.   mov    ax,[firstReg]
  1538.   out    dx,al
  1539.   mov    dx,3C9h
  1540.   mov    cx,[lastReg]            ; CX = number of registers
  1541.   sub    cx,ax
  1542.   inc    cx
  1543.   cld
  1544.  
  1545.     @@L1:
  1546.   in    al,dx
  1547.   shl    al,2
  1548.   stosb            ; red
  1549.   in    al,dx
  1550.   shl    al,2
  1551.   stosb            ; green
  1552.   in    al,dx
  1553.   shl    al,2
  1554.   stosb            ; blue
  1555.   loop    @@L1
  1556.  
  1557.     @@LExit:
  1558.   pop    di
  1559.   leave
  1560.   retf
  1561. ENDP
  1562.  
  1563.  
  1564. ;*****
  1565. ;***** clearGraphics
  1566. ;*****
  1567.  
  1568. PROC    C    clearGraphics_scr_copy
  1569.     ARG    colour:BYTE
  1570.   mov   dx,SC_INDEX
  1571.   mov   ax,0F02h
  1572.   out   dx,ax               ; enable writes to all four planes
  1573.  
  1574.   mov    ax,0A000h
  1575.   mov    es,ax
  1576.   xor    di,di
  1577.   cld
  1578.   mov    cx,16000
  1579.   mov    al,[colour]
  1580.   mov    ah,al
  1581.   rep    stosw
  1582.  
  1583.   leave
  1584.   retf
  1585. ENDP
  1586.  
  1587.  
  1588.     ENDS
  1589. END